package com.android.pa;

import java.util.Calendar;
import java.util.LinkedList;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

/**
 * The notification manager class is the interface between the personal
 * assistant inner methods and the alarm manager android service, it is given a
 * task or future schedule and it sets alarms for the beginning and ends of tasks
 * or edits and cancels them.
 */
public class NotificationManager
{

	Context _con;
	AlarmManager _alarmService = null;
	
	public NotificationManager(Context c)
	{
		_con = c;
		_alarmService = (AlarmManager) _con.getSystemService(Context.ALARM_SERVICE);
	}	

	/**
	 * The method that set's notifications, just give it a task and it will set
	 * a start and end notification for a task should also be used to update
	 * tasks, but not to cancel them.
	 * @param t the task that needs to have it's notifications set.
	 */
	public void setNotification(Task t)
	{
		// Create start and end pending intents.
		PendingIntent startPendingIntent = getPendingIntent(t, "start");
		PendingIntent endPendingIntent = getPendingIntent(t, "end");

		// Get the AlarmManager service.
		_alarmService = (AlarmManager) _con.getSystemService(Context.ALARM_SERVICE);

		// Set start alarm.
		_alarmService.set(	AlarmManager.RTC_WAKEUP, t.getStartTime().getTimeInMillis(),
							startPendingIntent);

		// Set end alarm.
		_alarmService.set(	AlarmManager.RTC_WAKEUP, t.getEndTime().getTimeInMillis(),
							endPendingIntent);
		Log.d("notification", "alarms set");
	}

	/**
	 * Create pending intent for the task's alarm.
	 * @param t the task.
	 * @param startEnd start/end.
	 * @return the pending intent.
	 */
	private PendingIntent getPendingIntent(Task t, String startEnd)
	{
		// Get time.
		Calendar time = startEnd.equals("start") ? t.getStartTime() : t.getEndTime();

		// Build intent and pending intent.
		Intent startIntent = new Intent(_con, AlarmReceiver.class)
				.putExtra("task", t)
				.putExtra("start/end", startEnd)
				// This flag means that it's the top intent in the intent stack, which
				// should help for all kinds of wakeup on sleep and stuff
				.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

		// Create task ID creator.
		int ID = t.hashCode() * 31 + time.hashCode();

		// We need to set an unique action because otherwise android thinks the
		// intents are the same and reuses them
		startIntent.setAction(startEnd + ID);

		// Not sure about the flags here, either cancel_current or
		// update_current should work.
		PendingIntent pendingIntent = 	PendingIntent.getBroadcast(_con, ID,
										startIntent, PendingIntent.FLAG_CANCEL_CURRENT);

		return pendingIntent;
	}

	/**
	 * Set alarms for tasks.
	 * @param hour
	 * @param minute
	 */
	public void setAlarms(LinkedList<Task> tasks)
	{
		for (Task t : tasks)
			setNotification(t);
	}

	/**
	 * Delete this task's alarm.
	 * @param t the task.
	 */
	public void deleteTask(Task t)
	{
		PendingIntent startPendingIntent = getPendingIntent(t, "start");
		PendingIntent endPendingIntent = getPendingIntent(t, "end");
		_alarmService.cancel(startPendingIntent);
		_alarmService.cancel(endPendingIntent);
	}

	/**
	 * Delete oldTask's alarm and schedule newTask's alarm.
	 * @param oldTask task to delete alarm for.
	 * @param newTask task to create alarm for.
	 */
	public void updateTask(Task oldTask, Task newTask)
	{
		deleteTask(oldTask);
		setNotification(newTask);
	}

}